import re

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler

from user.models import User, Info, Coupon


class UserShowSerializer(serializers.Serializer):
    user_id = serializers.IntegerField(source='id', read_only=True)
    username = serializers.CharField(read_only=True)
    tel = serializers.CharField(read_only=True)
    email = serializers.CharField(read_only=True)
    is_complete = serializers.CharField(read_only=True)
    user_or_seller = serializers.CharField(read_only=True)
    info_id_or_stall_id = serializers.IntegerField(read_only=True)


class UserlogonSerializer(serializers.Serializer):
    logon_username = serializers.CharField(write_only=True)
    logon_tel = serializers.CharField(write_only=True)
    logon_email = serializers.CharField(write_only=True)
    logon_password = serializers.CharField(write_only=True)
    logon_re_password = serializers.CharField(write_only=True)
    logon_ident = serializers.CharField(write_only=True)

    def validate(self, attrs):
        logon_username = attrs.get('logon_username')
        logon_tel = attrs.get('logon_tel')
        logon_email = attrs.get('logon_email')
        logon_password = attrs.get('logon_password')
        logon_re_password = attrs.get('logon_re_password')
        if len(logon_username) < 8:
            raise ValidationError('用户名不得小于8位')
        if len(logon_username) > 16:
            raise ValidationError('用户名不得大于16位')
        if len(logon_password) < 8 or len(logon_re_password) < 8:
            raise ValidationError('密码不得小于8位')
        if len(logon_password) > 16 or len(logon_re_password) > 16:
            raise ValidationError('密码不得大于16位')
        if logon_password != logon_re_password:
            raise ValidationError('两次输入的密码不一致')
        tel_re = re.match(r'^1[3456789]\d{9}$', logon_tel)
        if not tel_re:
            raise ValidationError('手机号码不合法')
        email_re = re.match(r'^.+@.+$', logon_email)
        if not email_re:
            raise ValidationError('邮箱格式不合法')
        user_1 = User.objects.filter(username=logon_username)
        user_2 = User.objects.filter(tel=logon_tel)
        user_3 = User.objects.filter(email=logon_email)
        if user_1 or user_2 or user_3:
            raise ValidationError('用户名/手机号/邮箱，已存在')
        return attrs

    def create(self, validated_data):
        logon_ident = validated_data.get('logon_ident')
        user_info = '0$' + logon_ident + '$0'
        instance = User.objects.create_user(
            username=validated_data.get('logon_username'),
            password=validated_data.get('logon_password'),
            tel=validated_data.get('logon_tel'),
            email=validated_data.get('logon_email'),
            user_info=user_info
        )
        return instance


class GuestInfoSerializer(serializers.Serializer):
    guest_nick_name = serializers.CharField(write_only=True)
    guest_camp = serializers.CharField(write_only=True)
    user_id = serializers.IntegerField(write_only=True)

    def validate(self, attrs):
        guest_nick_name = attrs.get('guest_nick_name')
        if len(guest_nick_name) > 12:
            raise ValidationError('昵称不得超过12位')
        info = Info.objects.filter(nickname=guest_nick_name)
        if info:
            raise ValidationError('昵称已存在')
        return attrs

    def create(self, validated_data):
        instance = Info.objects.create(
            nickname=validated_data.get('guest_nick_name'),
            camp=int(validated_data.get('guest_camp')),
            user_id=validated_data.get('user_id')
        )
        new_user_info = '1$1$' + str(instance.id)
        user = User.objects.filter(id=validated_data.get('user_id')).first()
        user.user_info = new_user_info
        user.save()
        return instance


class CodeImgShowSerializer(serializers.Serializer):
    code_img_url = serializers.CharField(read_only=True)
    is_most_handsome = serializers.BooleanField(read_only=True)
    is_most_old = serializers.BooleanField(read_only=True)
    is_most_fat = serializers.BooleanField(read_only=True)
    is_pw = serializers.BooleanField(read_only=True)
    is_most_fast = serializers.BooleanField(read_only=True)
    is_tsl = serializers.BooleanField(read_only=True)
    is_not_chinese = serializers.BooleanField(read_only=True)
    is_different = serializers.BooleanField(read_only=True)


class UserLoginSerializer(serializers.Serializer):
    login_username = serializers.CharField(write_only=True)
    login_password = serializers.CharField(write_only=True)
    login_ident = serializers.CharField(write_only=True)

    def validate(self, attrs):
        login_username = attrs.get('login_username')
        login_password = attrs.get('login_password')
        login_ident = attrs.get('login_ident')
        if re.match(r'^1[3-9][0-9]{9}$', login_username):
            user = User.objects.filter(tel=login_username).first()
        elif re.match(r'^.+@.+$', login_username):
            user = User.objects.filter(email=login_username).first()
        else:
            user = User.objects.filter(username=login_username).first()
        if not user:
            raise ValidationError('用户名不存在')
        check_rs = user.check_password(login_password)
        if not check_rs:
            raise ValidationError('登录密码错误')
        user_ident = user.user_info.split('$')[1]
        if user_ident != login_ident:
            raise ValidationError('用户类型错误')
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        self.context['user'] = user
        self.context['token'] = token
        return attrs


class GetUserInfoSerialize(serializers.Serializer):
    user_id = serializers.IntegerField(read_only=True)
    nickname = serializers.CharField(read_only=True)
    avatar_url = serializers.CharField(read_only=True)
    camp = serializers.IntegerField(read_only=True)
    level = serializers.IntegerField(read_only=True)
    current_exp = serializers.CharField(read_only=True)
    badge_1_num = serializers.IntegerField(read_only=True)
    badge_2_num = serializers.IntegerField(read_only=True)
    badge_3_num = serializers.IntegerField(read_only=True)
    badge_4_num = serializers.IntegerField(read_only=True)
    coupon_list = serializers.SerializerMethodField()

    def get_coupon_list(self, instance):
        coupon_list = []
        coupon_set = Coupon.objects.filter(user_id=instance.user_id)
        for coupon in coupon_set:
            data = {
                'total_price': coupon.total_price,
                'cut_price': coupon.cut_price,
                'coupon_id': coupon.id
            }
            coupon_list.append(data)
        return coupon_list


class UpdateNicknameSerializer(serializers.Serializer):
    username = serializers.CharField(write_only=True)
    nickname = serializers.CharField(write_only=True)

    def validate(self, attrs):
        print(attrs)
        username = attrs.get('username')
        nickname = attrs.get('nickname')
        user_info = Info.objects.filter(nickname=nickname)
        if user_info:
            raise ValidationError('用户名已存在')
        else:
            user = User.objects.filter(username=username).first()
            user_id = user.id
            Info.objects.filter(user_id=user_id).update(nickname=nickname)
            return attrs


class TrackShowSerializer(serializers.Serializer):
    user_id = serializers.CharField(read_only=True)
    stall_name = serializers.CharField(read_only=True)
    visit_time = serializers.CharField(read_only=True)
